この言語の標準API、特定のzipファイルが読めないんだが?


概要

ある言語でunzipできないzipファイルが見つかり、

シグニチャにpk34って書いてあるんで確実にzipだと思うんだが、実際にunzipできるかというとできない。

この謎を追う。


終わりのあたりにはpk78がある。うーん、他のヘッダは存在しないんだよなあ。なんなんだこれ。

-> 先にネタバレしておくと言語側の標準ライブラリがうんこだった。データディスクリプタありのzipをunzipできないんだってさ。ふーん。



解読

http://www.asahi-net.or.jp/~wr9k-oohs/Pages/Nigel%27s/Nigel57/nigel57.html 曰く、

pk34あるいはpk78がヘッダに入ることがある、、、?

よーわからんな、、

https://runicalp.hatenablog.com/entry/20100625/1277471095 曰く、

データディスクリプタっつーのがつくことがある、と。


・ローカルヘッダシグネチャ pk34

・データディスクリプタシグネチャ pk78


あーーーもしかしてzipだと思って接してたけどjarなのかこれ?馬鹿?

ローカルファイルヘッダ(pk34)にcrcとサイズが未定義の場合、このヘッダが定義される。ほー。


https://www.tnksoft.com/reading/zipfile/index.php?p=fmt5 曰く、

pk78のあとに入っているものは


・crc32 4byte

・圧縮後サイズ 4byte

・圧縮前サイズ 4byte

が入ってると。なるほど。


細かいフラグはここを参照するとして

https://gist.github.com/ysakasin/2edf8d3bf55c6ebf63f82851e302b030


っつーことで、RFCとかにも普通に書いてある事態だった。それなのに展開できないライブラリがあるのか。ふーん。


とりあえず引き続き値を読んでいく。



実際の値

50 4B 03 04 //4byte pk34

14 00 //2byte ver

          08 08 //2byte general purpose bit flag

08 00 //2byte 圧縮方式 = deflated

          xx xx //2byte 更新日時

xx xx //2byte 更新日

          00 00 ~

00 00 //4byte crc値

          00 00 ~

00 00 //4byte 圧縮後サイズ

          00 00 ~

00 00 //4byte 圧縮前サイズ

          xx xx //2byte ファイル名長さ

0000 //拡張データサイズ

          このへんからファイル名~

で、ビットフラグが0808なので、これは

0010 0010 で、3ビット目と7ビット目がたっている。

3bit目が立っている場合、データディスクリプタが書かれている。


~


50 4B 07 08 //pk78

xx xx xx xx //crc

xx xx xx xx //圧縮後サイズ

xx xx xx xx //圧縮前サイズ


なるほど。まあうーん変わった仕様だとは思うけど末尾に書けるとうれしいもんな、っていう、はい。RFCにも書いてある。

んでこれが読めないライブラリがあると。なるほどなあ。


ファイル名が書いてあってデータがあって長さは、、みたいなのが読めれば、あとはdeflateすればいいだけっぽいし。


-> できました。



いい話。